// iterator standard header
#pragma once
#ifndef _ITERATOR_
#define _ITERATOR_
#ifndef RC_INVOKED
#include <xutility>

#ifdef _MSC_VER
 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)
#endif  /* _MSC_VER */

_STD_BEGIN

		// TEMPLATE CLASS back_insert_iterator
template<class _Container>
	class back_insert_iterator
		: public _Outit
	{	// wrap pushes to back of container as output iterator
public:
	typedef _Container container_type;
	typedef typename _Container::reference reference;

	typedef _Range_checked_iterator_tag _Checked_iterator_category;

	explicit back_insert_iterator(_Container& _Cont)
		: container(&_Cont)
		{	// construct with container
		}

	back_insert_iterator<_Container>& operator=(
		typename _Container::const_reference _Val)
		{	// push value into container
		container->push_back(_Val);
		return (*this);
		}

	back_insert_iterator<_Container>& operator*()
		{	// pretend to return designated value
		return (*this);
		}

	back_insert_iterator<_Container>& operator++()
		{	// pretend to preincrement
		return (*this);
		}

	back_insert_iterator<_Container> operator++(int)
		{	// pretend to postincrement
		return (*this);
		}

protected:
	_Container *container;	// pointer to container
	};

		// TEMPLATE FUNCTION back_inserter
template<class _Container> inline
	back_insert_iterator<_Container> back_inserter(_Container& _Cont)
	{	// return a back_insert_iterator
	return (std::back_insert_iterator<_Container>(_Cont));
	}

		// TEMPLATE CLASS front_insert_iterator
template<class _Container>
	class front_insert_iterator
		: public _Outit
	{	// wrap pushes to front of container as output iterator
public:
	typedef _Container container_type;
	typedef typename _Container::reference reference;

	typedef _Range_checked_iterator_tag _Checked_iterator_category;

	explicit front_insert_iterator(_Container& _Cont)
		: container(&_Cont)
		{	// construct with container
		}

	front_insert_iterator<_Container>& operator=(
		typename _Container::const_reference _Val)
		{	// push value into container
		container->push_front(_Val);
		return (*this);
		}

	front_insert_iterator<_Container>& operator*()
		{	// pretend to return designated value
		return (*this);
		}

	front_insert_iterator<_Container>& operator++()
		{	// pretend to preincrement
		return (*this);
		}

	front_insert_iterator<_Container> operator++(int)
		{	// pretend to postincrement
		return (*this);
		}

protected:
	_Container *container;	// pointer to container
	};

		// TEMPLATE FUNCTION front_inserter
template<class _Container> inline
	front_insert_iterator<_Container> front_inserter(_Container& _Cont)
	{	// return front_insert_iterator
	return (std::front_insert_iterator<_Container>(_Cont));
	}

		// TEMPLATE CLASS insert_iterator
template<class _Container>
	class insert_iterator
		: public _Outit
	{	// wrap inserts into container as output iterator
public:
	typedef _Container container_type;
	typedef typename _Container::reference reference;

	typedef _Range_checked_iterator_tag _Checked_iterator_category;

	insert_iterator(_Container& _Cont, typename _Container::iterator _Where)
		: container(&_Cont), iter(_Where)
		{	// construct with container and iterator
		}

	insert_iterator<_Container>& operator=(
		typename _Container::const_reference _Val)
		{	// insert into container and increment stored iterator
		iter = container->insert(iter, _Val);
		++iter;
		return (*this);
		}

	insert_iterator<_Container>& operator*()
		{	// pretend to return designated value
		return (*this);
		}

	insert_iterator<_Container>& operator++()
		{	// pretend to preincrement
		return (*this);
		}

	insert_iterator<_Container>& operator++(int)
		{	// pretend to postincrement
		return (*this);
		}

protected:
	_Container *container;	// pointer to container
	typename _Container::iterator iter;	// iterator into container
	};

		// TEMPLATE FUNCTION inserter
template<class _Container,
	class _Iter> inline
	insert_iterator<_Container> inserter(_Container& _Cont, _Iter _Where)
	{	// return insert_iterator
	return (std::insert_iterator<_Container>(_Cont, _Where));
	}

		// TEMPLATE CLASS istream_iterator
template<class _Ty,
	class _Elem = char,
	class _Traits = char_traits<_Elem>,
	class _Diff = ptrdiff_t>
	class istream_iterator
		: public iterator<input_iterator_tag, _Ty, _Diff,
			const _Ty *, const _Ty&>
	{	// wrap _Ty extracts from input stream as input iterator
	typedef istream_iterator<_Ty, _Elem, _Traits, _Diff> _Myt;
public:
	typedef _Elem char_type;
	typedef _Traits traits_type;
	typedef basic_istream<_Elem, _Traits> istream_type;

#if _SECURE_SCL
	typedef _Range_checked_iterator_tag _Checked_iterator_category;
#endif

	istream_iterator()
		: _Myistr(0)
		{	// construct singular iterator
		}

	istream_iterator(istream_type& _Istr)
		: _Myistr(&_Istr)
		{	// construct with input stream
		_Getval();
		}

	const _Ty& operator*() const
		{	// return designated value

 #if _HAS_ITERATOR_DEBUGGING
		if (_Myistr == 0)
			{
			_DEBUG_ERROR("istream_iterator is not dereferencable");
			_SCL_SECURE_OUT_OF_RANGE;
			}
 #else
		_SCL_SECURE_VALIDATE_RANGE(_Myistr != 0);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		return (_Myval);
		}

	const _Ty *operator->() const
		{	// return pointer to class object
		return (&**this);
		}

	_Myt& operator++()
		{	// preincrement

 #if _HAS_ITERATOR_DEBUGGING
		if (_Myistr == 0)
			{
			_DEBUG_ERROR("istream_iterator is not incrementable");
			_SCL_SECURE_OUT_OF_RANGE;
			}
 #else
		_SCL_SECURE_VALIDATE_RANGE(_Myistr != 0);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		_Getval();
		return (*this);
		}

	_Myt operator++(int)
		{	// postincrement
		_Myt _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	bool _Equal(const _Myt& _Right) const
		{	// test for iterator equality
		return (_Myistr == _Right._Myistr);
		}

protected:
	void _Getval()
		{	// get a _Ty value if possible
		if (_Myistr != 0 && !(*_Myistr >> _Myval))
			_Myistr = 0;
		}

	static void _Xran()
		{	// report an out_of_range error
		_THROW(out_of_range, "invalid istream_iterator");
		}

	istream_type *_Myistr;	// pointer to input stream
	_Ty _Myval;	// lookahead value (valid if _Myistr is not null)
	};

		// istream_iterator TEMPLATE OPERATORS
template<class _Ty,
	class _Elem,
	class _Traits,
	class _Diff> inline
	bool operator==(
		const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Left,
		const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Right)
	{	// test for istream_iterator equality
	return (_Left._Equal(_Right));
	}

template<class _Ty,
	class _Elem,
	class _Traits,
	class _Diff> inline
	bool operator!=(
		const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Left,
		const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Right)
	{	// test for istream_iterator inequality
	return (!(_Left == _Right));
	}

		// TEMPLATE CLASS ostream_iterator
template<class _Ty,
	class _Elem = char,
	class _Traits = char_traits<_Elem> >
	class ostream_iterator
		: public _Outit
	{	// wrap _Ty inserts to output stream as output iterator
public:
	typedef _Elem char_type;
	typedef _Traits traits_type;
	typedef basic_ostream<_Elem, _Traits> ostream_type;

#if _SECURE_SCL
	typedef _Range_checked_iterator_tag _Checked_iterator_category;
#endif

	ostream_iterator(ostream_type& _Ostr,
		const _Elem *_Delim = 0)
		: _Myostr(&_Ostr), _Mydelim(_Delim)
		{	// construct from output stream and delimiter
		}

	ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val)
		{	// insert value into output stream, followed by delimiter
		*_Myostr << _Val;
		if (_Mydelim != 0)
			*_Myostr << _Mydelim;

 #if _HAS_ITERATOR_DEBUGGING
		if (!*_Myostr)
			{
			_DEBUG_ERROR("ostream_iterator is not dereferencable");
			_SCL_SECURE_OUT_OF_RANGE;
			}
 #else
		_SCL_SECURE_VALIDATE_RANGE(*_Myostr != NULL);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		return (*this);
		}

	ostream_iterator<_Ty, _Elem, _Traits>& operator*()
		{	// pretend to return designated value
		return (*this);
		}

	ostream_iterator<_Ty, _Elem, _Traits>& operator++()
		{	// pretend to preincrement
		return (*this);
		}

	ostream_iterator<_Ty, _Elem, _Traits> operator++(int)
		{	// pretend to postincrement
		return (*this);
		}

protected:
	static void _Xran()
		{	// report an out_of_range error
		_THROW(out_of_range, "invalid ostream_iterator");
		}

	const _Elem *_Mydelim;	// pointer to delimiter string (NB: not freed)
	ostream_type *_Myostr;	// pointer to output stream
	};

_STD_END

_STDEXT_BEGIN

// checked_iterator
template <class _Cont, class _Iter = typename _Cont::iterator>
	class checked_iterator
		: public _STD iterator<
			typename _STD iterator_traits<_Iter>::iterator_category, 
			typename _STD iterator_traits<_Iter>::value_type, 
			typename _STD iterator_traits<_Iter>::difference_type, 
			typename _STD iterator_traits<_Iter>::pointer, 
			typename _STD iterator_traits<_Iter>::reference>
	{
	friend class checked_iterator;
public:
	typedef checked_iterator<_Cont, _Iter> _Myt;
	typedef typename _STD iterator_traits<_Iter>::difference_type difference_type;
	typedef typename _STD iterator_traits<_Iter>::pointer pointer;
	typedef typename _STD iterator_traits<_Iter>::reference reference;

	typedef _STD _Range_checked_iterator_tag _Checked_iterator_category;
	typedef _Iter _Inner_type;

	typedef _Iter _Checked_iterator_base_type;
 
	_Checked_iterator_base_type _Checked_iterator_base() const
	{
		return _Current;
	}

	void _Checked_iterator_assign_from_base(_Checked_iterator_base_type _Base)
	{
		_Current = _Base;
	}

	// use default copy constructor and copy assignement

	checked_iterator()
		: _Mycont(NULL)
	{
	}

	checked_iterator(_Cont& _C, _Iter _Ptr)
		: _Mycont(&_C), _Current(_Ptr)
	{
	}

	checked_iterator(const _Myt &_Right)
		: _Mycont(_Right._Mycont), _Current(_Right._Current)
	{
	}

	template <class Iter2>
	checked_iterator(const checked_iterator<_Cont, Iter2> &_Right)
		: _Mycont(_Right._Mycont), _Current(_Right._Current)
	{
	}

	_Iter base() const
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
		return _Current;
	}

	template <class Iter2>
	bool operator==(const checked_iterator<_Cont, Iter2>& _Right) const
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont == _Right._Mycont);
		return _Current == _Right._Current;
	}

	template <class Iter2>
	bool operator!=(const checked_iterator<_Cont, Iter2>& _Right) const
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
		return !(*this == _Right);
	}

	template <class Iter2>
	bool operator<(const checked_iterator<_Cont, Iter2>& _Right) const
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL && _Mycont == _Right._Mycont);
		return _Current < _Right._Current;
	}

	template <class Iter2>
	bool operator>(const checked_iterator<_Cont, Iter2>& _Right) const
	{
		return _Right < *this;
	}

	template <class Iter2>
	bool operator<=(const checked_iterator<_Cont, Iter2>& _Right) const
	{
		return !(_Right < *this);
	}

	template <class Iter2>
	bool operator>=(const checked_iterator<_Cont, Iter2>& _Right) const
	{
		return !(*this < _Right);
	}

	reference operator*() const
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
		_SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Current != _Mycont->end());
		return *_Current;
	}

	pointer operator->() const
	{
		return (&**this);
	}

	_Myt& operator++()
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
		_SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Current != _Mycont->end());
		++_Current;
		return *this;
	}

	_Myt operator++(int)
	{
		_Myt _Tmp = *this;
		++*this;
		return _Tmp;
	}

	_Myt& operator--()
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
		_SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Current != _Mycont->begin());
		--_Current;
		return *this;
	}

	_Myt operator--(int)
	{
		_Myt _Tmp = *this;
		--*this;
		return _Tmp;
	}

	// random access iterators methods

	_Myt& operator+=(difference_type _Off)
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
		_SCL_SECURE_ALWAYS_VALIDATE_RANGE((_Mycont->end() - _Current) >= _Off && (_Mycont->begin() - _Current) <= _Off);
		_Current += _Off;
		return *this;
	}

	_Myt operator+(difference_type _Off) const
	{
		_Myt _Tmp = *this;
		return (_Tmp += _Off);
	}

	_Myt& operator-=(difference_type _Off)
	{
		return (*this += -_Off);
	}

	_Myt operator-(difference_type _Off) const
	{
		_Myt _Tmp = *this;
		return (_Tmp -= _Off);
	}

	difference_type operator-(const _Myt& _Right) const
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL && _Mycont == _Right._Mycont);
		return _Current - _Right._Current;
	}

	reference operator[](difference_type _Off) const
	{
		_SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
		_SCL_SECURE_ALWAYS_VALIDATE_RANGE((_Mycont->end() - _Current) > _Off && (_Mycont->begin() - _Current) <= _Off);
		return _Current[_Off];
	}

protected:
	void _Xran() const
	{	// report an out_of_range error
		_THROW(_STD out_of_range, "invalid checked_iterator<T> subscript");
	}

	void _Xinvarg() const
	{	// report an invalid_argument error
		_THROW(_STD invalid_argument, "invalid checked_iterator<T> argument");
	}

	_Cont *_Mycont; // the container of the iterator
	_Iter _Current; // the wrapped iterator
	};

_STDEXT_END

#ifdef _MSC_VER
 #pragma warning(pop)
 #pragma pack(pop)
#endif  /* _MSC_VER */

#endif /* RC_INVOKED */
#endif /* _ITERATOR_ */

/*
 * Copyright (c) 1992-2007 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 */

/*
 * This file is derived from software bearing the following
 * restrictions:
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this
 * software and its documentation for any purpose is hereby
 * granted without fee, provided that the above copyright notice
 * appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation.
 * Hewlett-Packard Company makes no representations about the
 * suitability of this software for any purpose. It is provided
 * "as is" without express or implied warranty.
 V5.03:0009 */
